package com.financing.wap.service.impl;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.financing.wap.common.ResultMap;
import com.financing.wap.common.ResultMap.STATUS;
import com.financing.wap.common.Session;
import com.financing.wap.common.SessionUtil;
import com.financing.wap.dao.ICorpDao;
import com.financing.wap.dao.IUserWechatDao;
import com.financing.wap.dto.AuthenticationDTO;
import com.financing.wap.dto.CompanyInvitationCodeDTO;
import com.financing.wap.dto.FaUserDTO;
import com.financing.wap.dto.FaUserWechatDTO;
import com.financing.wap.dto.RegisterDTO;
import com.financing.wap.dto.ShopperUserInfoDTO;
import com.financing.wap.dto.UserDTO;
import com.financing.wap.service.IActivitesService;
import com.financing.wap.service.IAuthenticationService;
import com.financing.wap.service.ICheckCodeService;
import com.financing.wap.service.IShopperUserInfoService;
import com.financing.wap.service.IUserService;
import com.financing.wap.service.IUserWechatService;
import com.financing.wap.service.IWechatCoreService;
import com.financing.wap.util.Constants;
import com.financing.wap.util.DTOdateSetUtil;
import com.financing.wap.util.IPUtil;
import com.financing.wap.util.PropertiesUtils;
import com.financing.wap.util.SecureUtil;
import com.financing.wap.util.Sign;
import com.financing.wap.util.StringUtil;
import com.financing.wap.util.WechatUtil;
import com.financing.wap.web.controller.api.WeixinController;
import com.financing.wap.weixin.dto.AccessTicket;
import com.financing.wap.weixin.dto.AccessToken;

@Service("wechatCoreServiceImpl")
public class WechatCoreServiceImpl implements IWechatCoreService {

	Logger logger = Logger.getLogger(getClass());

	@Autowired
	private IUserWechatDao userWechatDaoImpl;
	
	@Autowired
	private ICorpDao corpDao;

	@Autowired
	public IAuthenticationService authenticationService;

	@Autowired
	private IUserService userService;
	
	@Autowired
	private ICheckCodeService checkCodeServiceImpl;
	
	@Autowired
	public IActivitesService activitesService;
	
	@Autowired
	private IUserWechatService userWechatServiceImpl;
	
	@Autowired
	IShopperUserInfoService shopperUserInfoService;
	
	/**
	 * token
	 */
	private String token;
	
	/**
	 * Ticket
	 */
	private String ticket;
	
	// 间隔时间
	private int interval = 100 * 60 * 1000; // 100分钟

	// 刷新时间。默认当前时间
	private long refreshTime = System.currentTimeMillis();

	

	private final String appid = PropertiesUtils.getValue("open_appid");

	private final String secret = PropertiesUtils.getValue("open_secret");
	
	private final String mpappid = PropertiesUtils.getValue("mp_appid");

	private final String mpsecret = PropertiesUtils.getValue("mp_secret");
	
	private final String appappid = PropertiesUtils.getValue("app_appid");

	private final String appsecret = PropertiesUtils.getValue("app_secret");
	
	private final String tstappid = PropertiesUtils.getValue("tst_appid");

	private final String tstsecret = PropertiesUtils.getValue("tst_secret");

	private final String redirect_uri = PropertiesUtils.getValue("open_redirect_uri");

	@SuppressWarnings("deprecation")
	@Override
	public String getOpenWeixinLogin(HttpServletRequest request) {

		String state = request.getSession().getId().toString();

		return WechatUtil.getOpenWeixinLoginURL(appid,
				URLEncoder.encode(redirect_uri), state);
	}

	@Override
	public ResultMap openCallback(HttpServletRequest request)
			throws Exception {

		ResultMap remap = new ResultMap();

		// 第一步：请求CODE
		logger.info("in openCallback one get CODE.....................");

		String code = request.getParameter("code");

		if (StringUtil.isNullOrEmptyStr(code)) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_CODE_ERROR);
			return remap;
		}

		// 第二步：通过code获取access_token
		logger.info("in openCallback two get AccessToken..............");
		logger.info("in openCallback two get AccessToken..............appid:"+appid);
		logger.info("in openCallback two get AccessToken..............secret:"+secret);
		logger.info("in openCallback two get AccessToken..............code:"+code);

		Map<String, Object> map = WechatUtil.getOpenAccessToken(appid, secret,
				code);

		if (map == null) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ACCESS_TOKEN_ERROR);
			return remap;
		}

		String access_token = (String) map.get("access_token");
		String openid = (String) map.get("openid");

		// 第三步：通过access_token调用接口
		logger.info("in openCallback three get Userinfo...............");

		FaUserWechatDTO bean = WechatUtil.getOpenUserinfo(access_token, openid);

		if (bean == null || StringUtil.isNullOrEmptyStr(bean.getOpenid())
				|| StringUtil.isNullOrEmptyStr(bean.getUnionid())) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_USERINFO_ERROR);
			return remap;
		}
		// 判断数据库是否存在
		logger.info("in openCallback queryUserWechatInfo...............");
		if(StringUtils.isNotBlank(bean.getUnionid())){
			bean.setMpOpenid(null);
		}
		FaUserWechatDTO beanview = userWechatDaoImpl.queryUserWechatInfo(bean);
		
		//数据库不存在或者还未与用户关联
		if (beanview == null ) {
			// 初始化数据
			DTOdateSetUtil.setCreateInfo(bean);
			DTOdateSetUtil.setUpdateInfo(bean);
			userWechatDaoImpl.insertUserWechat(bean);
			remap.setStatus(STATUS.SUCCESS);
			remap.setAttribute("object", bean);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
			return remap;
		}else if (beanview.getUserId() != null) {
			remap.setStatus(STATUS.SUCCESS);
			remap.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
			remap.setAttribute("object", beanview);
			return remap;
		}else if (beanview.getUserId() == null){
			remap.setStatus(STATUS.SUCCESS);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
			remap.setAttribute("object", bean);
			return remap;
		}
		remap.setStatus(STATUS.SUCCESS);
		remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
		remap.setAttribute("object", bean);
		return remap;
	}

	@Override
	public ResultMap relationlogin(HttpServletRequest request, UserDTO user)
			throws SQLException {
		//1、验证登录用户合法
		ResultMap result = this.checkUser(user);
		//验证失败直接返回
		if(STATUS.FAILE.equals(result.getStatus())){
			logger.info("In apiweixin relationRegister checkUser FAILE!");
			return result;
		}
		logger.info("In apiweixin relationRegister checkUser SUCCESS!");
		user = (UserDTO)result.getAttribute("user");
		
		//2、关联用户
		result = this.relationWechat(user.getId());
		//关联失败直接返回
		if(STATUS.FAILE.equals(result.getStatus())){
			logger.info("In apiweixin relationRegister relationWechat FAILE!");
			return result;
		}
		logger.info("In apiweixin relationRegister relationWechat SUCCESS!");
		//3、登陆
		result = this.userLogin(user,request);
		
		return result;
	}

	/**
	 * 关联用户微信
	 * @param userId
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public ResultMap relationWechat(String userId) throws SQLException {
		
		logger.info("In apiweixin relationlogin userId is :"+userId);
		ResultMap resultweixin = new ResultMap();
		String wechatOpenid = (String)SessionUtil.getSession(true).getAttribute(WeixinController.WECHAT_OPENID);
		if(StringUtil.isNullOrEmptyStr(wechatOpenid)){
			
			logger.info("In apiweixin relationlogin wechatOpenid is null!");
			resultweixin.setStatus(STATUS.FAILE);
			resultweixin.setStatusCode(ResultMap.STATUS_CODE_WECHAT_RELATION_ERROR);
			resultweixin.setMessage("关联超时");
			return resultweixin;
		}
		FaUserWechatDTO bean = new FaUserWechatDTO();
		bean.setUnionid(wechatOpenid);
		logger.info("In apiweixin relationlogin wechatOpenid is :"+wechatOpenid);
		FaUserWechatDTO beanview = userWechatDaoImpl.queryUserWechatInfo(bean);
		if(beanview != null && beanview.getUserId() !=null){
			logger.info("In apiweixin relationlogin checkUser Have bound");
			resultweixin.setStatus(STATUS.FAILE);
			resultweixin.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ALREADY_OPENID_ERROR);
			resultweixin.setMessage("openid已经绑定!");
			return resultweixin;
		}
		bean.setUserId(userId);
		DTOdateSetUtil.setUpdateInfo(bean);
		//关联用户-数据库操作
		int i = userWechatDaoImpl.updateUserWechat(bean);
		if(i <= 0){
			logger.info("In apiweixin relationlogin updateUserWechat updateCount :"+i);
			resultweixin.setStatus(STATUS.FAILE);
			resultweixin.setStatusCode(ResultMap.STATUS_CODE_WECHAT_RELATION_ERROR);
			resultweixin.setMessage("关联失败");
			return resultweixin;
		}
		resultweixin.setStatus(STATUS.SUCCESS);
		resultweixin.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
		resultweixin.setMessage("关联成功");
		logger.info("In apiweixin relationlogin relationWechat SUCCESS");
		return resultweixin;
	}

	/**
	 * 验证用户是否合法
	 * @param user
	 * @return
	 */
	private ResultMap checkUser(UserDTO user) {
		ResultMap result = new ResultMap();
		try {
			//参数缺失判断，手机号、图形验证码、手机验证码、密码
			if(StringUtils.isEmpty(user.getLoginName()) || StringUtils.isEmpty(user.getPassword())){
				result.setStatus(STATUS.FAILE);
				result.setStatusCode(ResultMap.STATUS_CODE_PARAMETERS_LOSE);
				result.setMessage("参数缺失");
				return result;
			}
			
			// 对密码进行加密
			String password = user.getPassword();
			String securePassword = SecureUtil.MD5EncryptAndBase64(password);
			user.setPassword(securePassword);

			user = userService.getUserByUF(user);
			if (user != null) {

				// 用户状态验证
				if (Constants.FA_STATUS_DISABLE.equals(user.getFaStatus())) {
					logger.info("In apiweixin relationlogin checkUser Status 02");
					// 已经被禁用
					result.setStatus(STATUS.FAILE);
					result.setStatusCode(ResultMap.STATUS_CODE_ACCOUNT_DISABLE);
					result.setMessage("用户已经被禁用");
					return result;

				}
				// 已经被拉黑 判断
				if (Constants.FA_STATUS_BLACK.equals(user.getFaStatus())) {
					logger.info("In apiweixin relationlogin checkUser Status 02");
					// 已经被禁用
					result.setStatus(STATUS.FAILE);
					result.setStatusCode(ResultMap.STATUS_CODE_ACCOUNT_BLACK);
					result.setMessage("用户已经被拉黑");
					return result;

				}
				
				FaUserWechatDTO bean = new FaUserWechatDTO();
				bean.setUserId(user.getId());
				if(userWechatDaoImpl.queryUserWechatInfo(bean) != null){
					logger.info("In apiweixin relationlogin checkUser Have bound");
					result.setStatus(STATUS.FAILE);
					result.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ALREADY_USER_ERROR);
					result.setMessage("用户已经绑定!");
					return result;
				}
				result.setAttribute("user", user);
				result.setStatus(STATUS.SUCCESS);
				result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
				result.setMessage("用户名验证成功");
			} else {
				result.setStatus(STATUS.FAILE);
				result.setStatusCode(ResultMap.STATUS_CODE_PWS_ERROR);
				result.setMessage("用户名密码错误");
			}
		} catch (Exception e) {
			logger.error("checkUser  error", e);
			result.setStatus(STATUS.FAILE);
			result.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);
		}
		logger.info("In apiweixin relationlogin checkUser SUCCESS");
		return result;
	}

	/**
	 * 用户登陆
	 * @param user
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private ResultMap userLogin(UserDTO user, HttpServletRequest request) {
		ResultMap result = new ResultMap();
		try {
				Session session = SessionUtil.getSession(true);
				session.setLogin(true);
				session.setUser(user);
				SessionUtil.setSession(session);
				AuthenticationDTO auth = authenticationService
						.queryAuthInfo(user.getId());

				String returnUrl = (String) session.getAttribute("returnUrl");
				Map<String, Object> parameterMap = (Map<String, Object>) session
						.getAttribute("returnParameterMap");
				String returnMethod = (String) session
						.getAttribute("returnMethod");
				result.setAttribute("returnUrl", returnUrl);
				result.setAttribute("params", parameterMap);
				result.setAttribute("method", returnMethod);

				result.setAttribute("userType", user.getUType());
				result.setAttribute("uRole", user.getRole());
				result.setAttribute("reviewStatus", "0");
				result.setAttribute("loginName",user.getLoginName());
				if (auth != null) {
					result.setAttribute("reviewStatus", auth.getReviewStatus());
				}
				if (StringUtils.isBlank(user.getUserName())) {
					result.setAttribute("uName", "");
				} else {
					result.setAttribute("uName", user.getUserName());
				}

				FaUserDTO userTmp = new FaUserDTO();
				userTmp.setId(user.getId());
				userTmp.setLastLoginIP(IPUtil.getRemoteHost(request));
				userTmp.setLastLoginTime(new Date());
				userService.updateFaUserInfo(userTmp);

				result.setAttribute("id", user.getId());
				result.setAttribute("lastLoginIP", user.getLastLoginIP());
				result.setAttribute("lastLoginTime", user.getLastLoginTime());
				result.setAttribute("uImage", user.getuImage());
				
				//wap_jee_1.1 加入微信信息
				FaUserWechatDTO faUserWechatDTO =  new FaUserWechatDTO();
				faUserWechatDTO.setUserId(user.getId());
				faUserWechatDTO = userWechatServiceImpl.queryUserWechatInfo(faUserWechatDTO);
				if(faUserWechatDTO != null){
					result.setAttribute("headimgurl", faUserWechatDTO.getHeadimgurl());
					result.setAttribute("nickname", faUserWechatDTO.getNickname());
				}
				
				//查询店主个人信息
				try {
					ShopperUserInfoDTO shopperUserInfo=new ShopperUserInfoDTO();
					//用户id
					shopperUserInfo.setUserId(user.getId());
					ShopperUserInfoDTO shopperUserInfoDto = shopperUserInfoService.queryListGetFirst(shopperUserInfo);
					result.setAttribute("shopperUserInfoDto",shopperUserInfoDto);
				} catch (Exception e) {
					logger.error("get ShopperUserInfoDTO error",e);
				}
				
				result.setStatus(STATUS.SUCCESS);
				result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
				result.setMessage("登陆成功");
			
		} catch (Exception e) {
			logger.error("userLogin error", e);
			result.setStatus(STATUS.FAILE);
			result.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);
			result.setMessage("登陆失败");
		}
		logger.info("In apiweixin relationlogin userLogin SUCCESS");
		return result;
	}

	@Override
	public ResultMap relationRegister(HttpServletRequest request,
			RegisterDTO register) throws Exception {
		
		ResultMap result = new ResultMap();
		//1、验证注册信息
		result = this.checkInfo(request,register);
		//失败直接返回
		if(STATUS.FAILE.equals(result.getStatus())){
			logger.info("In apiweixin relationRegister checkInfo FAILE!");
			return result;
		}
		logger.info("In apiweixin relationRegister checkInfo SUCCESS!");
		
		//2、创建用户
		result = this.registerUser( register);
		//失败直接返回
		if(STATUS.FAILE.equals(result.getStatus())){
			logger.info("In apiweixin relationRegister registerUser FAILE!");
			return result;
		}
		logger.info("In apiweixin relationRegister registerUser SUCCESS!");
		UserDTO user  = (UserDTO) result.getAttribute("user");
		//3、关联用户
		result = this.relationWechat(user.getId());
		//失败直接返回
		if(STATUS.FAILE.equals(result.getStatus())){
			logger.info("In apiweixin relationRegister relationWechat FAILE!");
			return result;
		}
		logger.info("In apiweixin relationRegister relationWechat SUCCESS!");
		//4、登陆
		result = this.userLogin(user,request);
		
		//获取accountId
		user = userService.getUserByUF(user);
		//5、送红包
		activitesService.operatingActivities(Constants.ACTIVITIES_CODE_ING,user);
		return result;
	}

	/**
	 * 注册用户
	 * @param register
	 * @return
	 */
	private ResultMap registerUser(RegisterDTO register){
		ResultMap result = new ResultMap();
		try{
			//对密码进行加密
			String password = register.getPassword();
			String securePassword = SecureUtil.MD5EncryptAndBase64(password);
			
			
			UserDTO user = new UserDTO();
			user.setLoginName(register.getMobile());
			user.setMobile(register.getMobile());
			user.setPassword(securePassword);
			String sourceCodeInt = "0";
			
			//加入广告来源注册sourceCode
			user.setMediaSource(StringUtil.isNullOrEmptyStr((String) SessionUtil.getSession().getAttribute("mid"))?Constants.MEDIA_SOURCE_PT:(String) SessionUtil.getSession().getAttribute("mid"));
			
			//注册来源手机号  如果为空  sourceCodeInt 取 register.getSourceCode()
			//注册来源手机号  如果不为空 查询数据库  sourceCodeInt 取 userID 对象为空 ourceCodeInt 取 register.getSourceCode()
			if(StringUtil.isNullOrEmptyStr(register.getSourceMobile())){
				sourceCodeInt = StringUtil.isNullOrEmptyStr(register.getSourceCode())?"0":register.getSourceCode();
				
			}else{
				UserDTO userSource = new UserDTO();
				userSource.setLoginName(register.getSourceMobile());
				userSource = userService.queryUserByMobile(userSource);
				if(userSource == null){
					sourceCodeInt = StringUtil.isNullOrEmptyStr(register.getSourceCode())?"0":register.getSourceCode();
				}else{
					sourceCodeInt = userSource.getId();
				}
			}
			
			user.setRemark((String)SessionUtil.getSession().getAttribute("wi"));
			user.setSourceCode(sourceCodeInt);
			//活动来源-从前端传入
			logger.info("actSource : "+register.getActSource());
			user.setActSource(register.getActSource());
			//校验数据格式
			
			//判断是否为机构下面的账号
			if(!StringUtil.isNullOrEmptyStr(register.getSourceMobile())){
				CompanyInvitationCodeDTO cic = new CompanyInvitationCodeDTO();
				cic.setCompanyInvitationCode(register.getSourceMobile().trim());
				cic = corpDao.getCorpInvitationCode(cic);
				//邀请码为机构邀请码
				if(cic!=null&& cic.getCompanyId()!= null){
					user.setManagerId(cic.getCompanyId());
					//设置fa用户类型为机构fa
					user.setuType("3");
				}else{
					UserDTO u = new UserDTO();
					u.setLoginName(register.getSourceMobile());
					u = userService.queryUserByMobile(user);
					if(u!=null && "1".equals(u.getuType())){
						user.setManagerId(u.getId());
						//设置fa用户类型为机构fa
						user.setuType("3");
					}
				}
			}
			
			//创建用户
			userService.registerUser(user);
			
			result.setAttribute("user", user);
			result.setStatus(STATUS.SUCCESS);
			result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
		} catch (Exception e) {
			logger.error("registerUser error", e);
			result.setStatus(STATUS.FAILE);
			result.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);
		}
		
		return result;
	}
	
	/**验证注册信息
	 * @param request
	 * @param register
	 * @return
	 * @throws SQLException 
	 */
	private ResultMap checkInfo(HttpServletRequest request,RegisterDTO register) throws SQLException{
		ResultMap result = new ResultMap();
		
		//参数缺失判断，手机号、图形验证码、手机验证码、密码
		//|| StringUtils.isEmpty(request.getParameter("verifyCode"))
		if(StringUtils.isEmpty(register.getMobile())  || StringUtils.isEmpty(register.getvCode())
				|| StringUtils.isEmpty(register.getPassword())){
			result.setStatus(STATUS.FAILE);
			result.setStatusCode(ResultMap.STATUS_CODE_PARAMETERS_LOSE);
			result.setMessage("参数缺失");
			return result;
		}
		
		/*//图形验证码校验
		String platformtype = request.getParameter("platformtype");
		if(StringUtils.isEmpty(platformtype)||!"2".equals(platformtype)){
			String verifyCode = (String)SessionUtil.getSession().getAttribute(Constants.SESSION_KEY_VERIFYCODE);
			String requestVerifyCode = request.getParameter("verifyCode");
			SessionUtil.getSession().setAttribute(Constants.SESSION_KEY_VERIFYCODE, null);
			logger.info("verifyCode is :"+verifyCode);
			logger.info("requestVerifyCode is :"+requestVerifyCode);
			if(StringUtils.isEmpty(verifyCode)||!verifyCode.equals(requestVerifyCode.toLowerCase())){
				result.setStatus(STATUS.FAILE);
				result.setStatusCode(ResultMap.LOGIN_VERIFYCODE_ERROR);
				result.setMessage("图片验证码错误");
				return result;
			}
		}*/
		
		//是否已经注册
		if(userService.isMobileRegistered(register.getMobile())){
			logger.info("repeat mobile no");
			//已经被注册
			result.setStatus(ResultMap.STATUS.FAILE);
			result.setStatusCode(ResultMap.STATUS_CODE_MOBILE_NUMBER_CONFLICT);
			result.setMessage("手机号码已经被注册！");
			return result;
		}
		// 校验手机验证码
		if (checkCodeServiceImpl.CheckCodeSwitch()) {
			result = checkCodeServiceImpl.checkOtpCode(register.getMobile(),register.getvCode());
			if (!STATUS.SUCCESS.equals(result.getStatus())) {
				return result;
			}
		}
		String wechatOpenid = (String)SessionUtil.getSession(true).getAttribute(WeixinController.WECHAT_OPENID);
		if(StringUtil.isNullOrEmptyStr(wechatOpenid)){
			
			logger.info("In apiweixin relationlogin wechatOpenid is null!");
			result.setStatus(STATUS.FAILE);
			result.setStatusCode(ResultMap.STATUS_CODE_WECHAT_RELATION_ERROR);
			result.setMessage("关联超时");
			return result;
		}
		FaUserWechatDTO bean = new FaUserWechatDTO();
		bean.setUnionid(wechatOpenid);
		logger.info("In apiweixin relationlogin wechatOpenid is :"+wechatOpenid);
		FaUserWechatDTO beanview = userWechatDaoImpl.queryUserWechatInfo(bean);
		if(beanview != null && beanview.getUserId() !=null){
			logger.info("In apiweixin relationlogin checkUser Have bound");
			result.setStatus(STATUS.FAILE);
			result.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ALREADY_OPENID_ERROR);
			result.setMessage("openid已经绑定!");
			return result;
		}
		result.setStatus(ResultMap.STATUS.SUCCESS);
		return result;
	}

	@Override
	public ResultMap mpCallbackNotAuth(HttpServletRequest request) throws Exception {
		ResultMap remap = new ResultMap();

		// 第一步：请求CODE
		logger.info("in openCallback one get CODE.....................");

		String code = request.getParameter("code");

		if (StringUtil.isNullOrEmptyStr(code)) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_CODE_ERROR);
			return remap;
		}

		// 第二步：通过code获取access_token
		logger.info("in openCallback two get AccessToken..............");

		Map<String, Object> map = WechatUtil.getOpenAccessToken(mpappid, mpsecret,
				code);

		if (map == null) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ACCESS_TOKEN_ERROR);
			return remap;
		}

		String openid = (String) map.get("openid");
		
		remap.setAttribute("openId", openid);
		remap.setStatus(STATUS.SUCCESS);
		remap.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
		return remap;
	}
	
	@Override
	public ResultMap mpCallback(HttpServletRequest request) throws Exception {
		ResultMap remap = new ResultMap();

		// 第一步：请求CODE
		logger.info("in openCallback one get CODE.....................");

		String code = request.getParameter("code");

		if (StringUtil.isNullOrEmptyStr(code)) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_CODE_ERROR);
			return remap;
		}

		// 第二步：通过code获取access_token
		logger.info("in openCallback two get AccessToken..............");

		Map<String, Object> map = WechatUtil.getOpenAccessToken(mpappid, mpsecret,
				code);

		if (map == null) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ACCESS_TOKEN_ERROR);
			return remap;
		}

		String access_token = (String) map.get("access_token");
		String openid = (String) map.get("openid");

		// 第三步：通过access_token调用接口
		logger.info("in openCallback three get Userinfo...............");

		FaUserWechatDTO bean = WechatUtil.getOpenUserinfo(access_token, openid);

		if (bean == null || StringUtil.isNullOrEmptyStr(bean.getOpenid())
				) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_USERINFO_ERROR);
			return remap;
		}
		// 判断数据库是否存在
		logger.info("in openCallback queryUserWechatInfo...............");
		FaUserWechatDTO beanQuery = new  FaUserWechatDTO();
		if(StringUtils.isNotBlank(bean.getUnionid())){
			beanQuery.setUnionid(bean.getUnionid());
		}else{
			beanQuery.setMpOpenid(bean.getOpenid());
		}
		
		logger.info("unionid====================="+beanQuery.getUnionid());
		logger.info("MpOpenid====================="+beanQuery.getOpenid());
		FaUserWechatDTO beanview = userWechatDaoImpl.queryUserWechatInfo(beanQuery);
		
		//数据库不存在或者还未与用户关联
		if (beanview == null ) {
			logger.info("in openCallback userWechatDaoImpl.insertUserWechat...............");
			// 初始化数据
			DTOdateSetUtil.setCreateInfo(bean);
			DTOdateSetUtil.setUpdateInfo(bean);
			bean.setMpOpenid(bean.getOpenid());
			userWechatDaoImpl.insertUserWechat(bean);
			remap.setStatus(STATUS.SUCCESS);
			remap.setAttribute("object", bean);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
			return remap;
		}else {
			//如果更新用户微信信息
			FaUserWechatDTO updateBean = new FaUserWechatDTO();
			DTOdateSetUtil.setUpdateInfo(updateBean);
		
			updateBean.setMpOpenid(bean.getOpenid());
	
			updateBean.setCity(bean.getCity());
			updateBean.setCountry(bean.getCountry());
			updateBean.setNickname(bean.getNickname());
			updateBean.setHeadimgurl(bean.getHeadimgurl());
			updateBean.setUnionid(bean.getUnionid());
			updateBean.setMpOpenid(bean.getOpenid());
			userWechatDaoImpl.updateUserWechat(updateBean);

			logger.info("in openCallback userWechatDaoImpl.updateUserWechat...............begin");
			logger.info("in openCallback userWechatDaoImpl.updateUserWechat...............bean.getOpenid():"+bean.getOpenid());
			logger.info("in openCallback userWechatDaoImpl.updateUserWechat...............bean.getNickname():"+bean.getNickname());
			logger.info("in openCallback userWechatDaoImpl.updateUserWechat...............bean.getHeadimgurl();"+bean.getHeadimgurl());
			logger.info("in openCallback userWechatDaoImpl.updateUserWechat...............end");
			logger.info("in openCallback userWechatDaoImpl.updateUserWechat...............");

			if (beanview.getUserId() != null) {
				remap.setStatus(STATUS.SUCCESS);
				remap.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
				remap.setAttribute("object", beanview);
				return remap;
			}else if (beanview.getUserId() == null){
				remap.setStatus(STATUS.SUCCESS);
				remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
				remap.setAttribute("object", bean);
				return remap;
			}
		}
		remap.setStatus(STATUS.SUCCESS);
		remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
		remap.setAttribute("object", bean);
		return remap;
	}
	@Override
	public ResultMap appCallback(HttpServletRequest request) throws Exception {


		ResultMap remap = new ResultMap();

		// 第一步：请求CODE
		logger.info("in appCallback one get CODE.....................");

		String code = request.getParameter("code");

		if (StringUtil.isNullOrEmptyStr(code)) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_CODE_ERROR);
			return remap;
		}

		// 第二步：通过code获取access_token
		logger.info("in appCallback two get AccessToken..............");
		logger.info("in appCallback two get AccessToken..............open_appid:"+appid);
		logger.info("in appCallback two get AccessToken..............open_secret:"+secret);
		logger.info("in appCallback two get AccessToken..............code:"+code);

		Map<String, Object> map = WechatUtil.getOpenAccessToken(appappid, appsecret,
				code);

		if (map == null) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ACCESS_TOKEN_ERROR);
			return remap;
		}

		String access_token = (String) map.get("access_token");
		String openid = (String) map.get("openid");

		// 第三步：通过access_token调用接口
		logger.info("in appCallback three get Userinfo...............");

		FaUserWechatDTO bean = WechatUtil.getOpenUserinfo(access_token, openid);

		if (bean == null || StringUtil.isNullOrEmptyStr(bean.getOpenid())
				|| StringUtil.isNullOrEmptyStr(bean.getUnionid())) {
			remap.setStatus(STATUS.FAILE);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_USERINFO_ERROR);
			return remap;
		}
		// 判断数据库是否存在
		logger.info("in appCallback queryUserWechatInfo...............");
		if(StringUtils.isNotBlank(bean.getUnionid())){
			bean.setMpOpenid(null);
		}
		FaUserWechatDTO beanview = userWechatDaoImpl.queryUserWechatInfo(bean);
		
		//数据库不存在或者还未与用户关联
		if (beanview == null ) {
			// 初始化数据
			bean.setMpOpenid(openid);
			DTOdateSetUtil.setCreateInfo(bean);
			DTOdateSetUtil.setUpdateInfo(bean);
			userWechatDaoImpl.insertUserWechat(bean);
			remap.setStatus(STATUS.SUCCESS);
			remap.setAttribute("object", bean);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
			return remap;
		}else if (beanview.getUserId() != null) {
			remap.setStatus(STATUS.SUCCESS);
			remap.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
			remap.setAttribute("object", beanview);
			return remap;
		}else if (beanview.getUserId() == null){
			remap.setStatus(STATUS.SUCCESS);
			remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
			remap.setAttribute("object", bean);
			return remap;
		}
		remap.setStatus(STATUS.SUCCESS);
		remap.setStatusCode(ResultMap.STATUS_CODE_WECHAT_ASSOCIATED_USER_ERROR);
		remap.setAttribute("object", bean);
		return remap;
	}
	@SuppressWarnings("deprecation")
	@Override
	public ResultMap getjsApiwxconfig(HttpServletRequest request)
			throws Exception {
		ResultMap remap = new ResultMap();

		String requestUrl = request.getParameter("requestUrl");
		
		if(StringUtil.isNullOrEmptyStr(requestUrl)){
			remap.setStatus(STATUS.ERROR);
			remap.setStatusCode(ResultMap.STATUS_CODE_PARAMETERS_LOSE);
			return remap;
		}
		logger.info("WechatCoreServiceImpl getjsApiwxconfig requestUrl:"
				+ requestUrl);
		requestUrl = URLDecoder.decode(requestUrl);
		logger.info("WechatCoreServiceImpl getjsApiwxconfig URLDecoder requestUrl:"
				+ requestUrl);
		// 获取 ticket
		checkAccessTokenAndTicket();
		logger.info("WechatCoreServiceImpl getjsApiwxconfig ticket:"
				+ ticket);
		// 根据 ticket 生成 sign
		Map<String, String> map = Sign.sign(ticket, requestUrl);
		remap.setAttribute("dto", map);
		remap.setStatus(STATUS.SUCCESS);
		remap.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
		return remap;
	}

	private void checkAccessTokenAndTicket() {
		long current = System.currentTimeMillis();
		// 是否刷新 jsApiwxconfig
		if (refreshTime < current || ticket == null) {

			logger.info("checkAccessTokenAndTicket getNextRefreshTime begin");

			refreshTime = getNextRefreshTime(current, interval);
			// 1、获取access_token
			AccessToken accessToken = WechatUtil.getAccessToken(mpappid,
					mpsecret);
			this.token = accessToken.getToken();
			// 2、获取jsapi_ticket
			AccessTicket accessTicket = WechatUtil.getAccessTicket(token);
			this.ticket = accessTicket.getTicket();

			logger.info("checkAccessTokenAndTicket getNextRefreshTime end");

		}
	}

	/**
	 * 获得下一个刷新时间。
	 * 
	 * @param current
	 * @param interval
	 * @return 随机间隔时间
	 */
	private long getNextRefreshTime(long current, int interval) {
		return current + interval;
		// 为了防止多个应用同时刷新，间隔时间=interval+RandomUtils.nextInt(interval/4);
		// return current + interval + RandomUtils.nextInt(interval / 4);
	}

	@Override
	public boolean getFilePath(String imgServerId,String filePath) throws Exception {
		if(StringUtils.isBlank(imgServerId) || StringUtils.isBlank(filePath)){
			return false;
		}

		// 1、获取access_token
		AccessToken accessToken = WechatUtil.getAccessToken(mpappid,mpsecret);
		logger.info("getFilePathImgServerId:"+imgServerId);
		logger.info("getFilePathToken:"+accessToken.getToken());
		return WechatUtil.saveImageToDisk(imgServerId, accessToken.getToken(), filePath);
	}


}
